/**
 * This file is part of 1genia trampoline
 * Copyright (C) 2007-2008 1genia (contact@1genia.com)
 *
 * This library is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; version 3 of the License. 
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details. 
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; see the file COPYING.TXT.  If not,
 * write to the Free Software Foundation, Inc., 51 Franklin Street,
 * Fifth Floor, Boston, MA 02110-1301, USA. 
 **/
package com.genia.toolbox.web.gwt.basics.client.widget;

import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.ClickListenerCollection;
import com.google.gwt.user.client.ui.HasHTML;
import com.google.gwt.user.client.ui.HasText;
import com.google.gwt.user.client.ui.SourcesClickEvents;
import com.google.gwt.user.client.ui.Widget;

/**
 * a button with an hyperlink around it.
 */
public class HyperLinkButton
    extends Widget
    implements HasHTML, SourcesClickEvents, HasText

{
  /**
   * the {@link Element} representing the button.
   */
  private Element buttonElement;

  /**
   * the {@link ClickListener} aggregating all declared {@link ClickListener}s.
   */
  private ClickListenerCollection clickListeners;



  /**
   * Creates an empty {@link HyperLinkButton}.
   */
  public HyperLinkButton()
  {
    setElement(DOM.createAnchor());
    DOM.setElementProperty(getElement(), "href", "javacript:;");
    DOM.appendChild(getElement(), buttonElement = DOM.createButton());
    sinkEvents(Event.ONCLICK);
    setStyleName("gwt-HyperlinkButton");
  }



  /**
   * Adds a listener interface to receive click events.
   * 
   * @param listener
   *          the listener interface to add
   */
  public void addClickListener(ClickListener listener)
  {
    if (clickListeners == null) {
      clickListeners = new ClickListenerCollection();
    }
    clickListeners.add(listener);
  }



  /**
   * Gets this object's contents as HTML.
   * 
   * @return the object's HTML
   */
  public String getHTML()
  {
    return DOM.getInnerHTML(buttonElement);
  }



  /**
   * Gets this object's text.
   * 
   * @return the object's text
   */
  public String getText()
  {
    return DOM.getInnerText(buttonElement);
  }



  /**
   * getter for the enabled property.
   * 
   * @return the enabled
   */
  public boolean isEnabled()
  {
    return !DOM.getElementPropertyBoolean(buttonElement, "disabled");
  }



  /**
   * method called each time a registered event happen.
   * 
   * @param event
   *          the event happening.
   */
  @Override
  public void onBrowserEvent(Event event)
  {
    if (DOM.eventGetType(event) == Event.ONCLICK) {
      if (isEnabled() && clickListeners != null) {
        clickListeners.fireClick(this);
      }
      DOM.eventPreventDefault(event);
    }
  }



  /**
   * Removes a previously added listener interface.
   * 
   * @param listener
   *          the listener interface to remove
   */
  public void removeClickListener(ClickListener listener)
  {
    if (clickListeners != null) {
      clickListeners.remove(listener);
    }
  }



  /**
   * setter for the enabled property.
   * 
   * @param enabled
   *          the enabled to set
   */
  public void setEnabled(boolean enabled)
  {
    DOM.setElementPropertyBoolean(buttonElement, "disabled", !enabled);
  }



  /**
   * Sets this object's contents via HTML. Use care when setting an object's
   * HTML; it is an easy way to expose script-based security problems. Consider
   * using {@link #setText(String)} whenever possible.
   * 
   * @param html
   *          the object's new HTML
   */
  public void setHTML(String html)
  {
    DOM.setInnerHTML(buttonElement, html);
  }



  /**
   * Sets this object's text.
   * 
   * @param text
   *          the object's new text
   */
  public void setText(String text)
  {
    DOM.setInnerText(buttonElement, text);
  }
}
